/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pagrafo.genetico;

import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * @author Fabricio
 */
public class SelecaoRoleta {
    
    //private static final int[] repeticao = new int[]{10,8,6,4,3,1};
    //private static final int[] repeticao = new int[]{6,5,4,3,2,1};
    //private static final int[] repeticao = new int[]{4,3,2,2,2,1};
    //private static final int[] repeticao = new int[]{4,2,1,1,1,1};
    //private static final int[] repeticao = new int[]{30,10,5,5,1,10};
    //private static final int[] repeticao = new int[]{30,10,1,1,1,0};
    //private static final int[] repeticao = new int[]{5,4,3,2,1,0};
    //private static final int[] repeticao = new int[]{4,2,1,1,1,0};
    //private static final int[] repeticao = new int[]{4,2,2,1,1,1};
    private static final int[] repeticao = new int[]{4,2,2,2,1,1,1,1,1,1,0};
    
    public static ArrayList<Cromossomo> selecionar2(ArrayList<Cromossomo> cromossomos, int n){
        
        ArrayList<Cromossomo> selecionados = new ArrayList<Cromossomo>();
        
        //Ordena a lista original
        Collections.sort(cromossomos);
        
        //preserva o melhor
        selecionados.add(cromossomos.get(0));
        n--;
        
        //Pega o score do pior cromossomo
        double scoreMax = cromossomos.get(cromossomos.size()-1).getScore();
        
        //Vetor para controlar os cromossomos que já foram adicionados
        boolean[] adicionado = new boolean[cromossomos.size()];
        
        ArrayList<Integer> roleta = new ArrayList<Integer>();
        
        //System.out.println("##################################### " + cromossomos.size());
        
        //Preenche a roleta
        for (int i = 0; i < cromossomos.size(); i++) {
            
            //Calcula o score relativo do cromossomo com base no pior cromossomo
            double scoreRelativo = cromossomos.get(i).getScore()/scoreMax;
            //System.out.println(scoreRelativo);
            
            //Número de repetições do cromossomo na roleta
            int r = 1;
            
            //Quanto menor o escore relativo melhor o cromossomo
            if (scoreRelativo <= 0.1) {
                r = repeticao[0];
            } else if (scoreRelativo > 0.1 && scoreRelativo <= 0.3) {
                r = repeticao[1];
            } else if (scoreRelativo > 0.3 && scoreRelativo <= 0.5) {
                r = repeticao[2];
            } else if (scoreRelativo > 0.5 && scoreRelativo <= 0.7) {
                r = repeticao[3];
            } else if (scoreRelativo > 0.7 && scoreRelativo <= 0.9) {
                r = repeticao[4];
            } else if (scoreRelativo > 0.9) {
                r = repeticao[5];
            }
            
            for (int j = 0; j < r; j++) {
                    roleta.add(Integer.valueOf(i));
            }
        }
        
        //Embaralha a roleta
        Collections.shuffle(roleta);
        
        //Controla quantos cromossomos já foram adicionados
        int preenchidos = 0;
        
        //Seleciona com base na roleta
        for (int i = 0; i < roleta.size(); i++) {
            
            //Caso a lista de cromossomos esteja preenchida termina de preencher
            if(preenchidos == n){
                break;
            }
            
            int p = roleta.get(i).intValue();
            
            //Caso o cromossomo já tenha sido adicionado continua procurando
            if(adicionado[p]){
                continue;
            }
            
            //Adiciona o cromossomo e faz o controle
            selecionados.add(cromossomos.get(p));
            adicionado[p] = true;
            preenchidos++;
        }
        
        
        return selecionados;
    }
    
    public static ArrayList<Cromossomo> selecionar(ArrayList<Cromossomo> cromossomos, int n){
        
        ArrayList<Cromossomo> selecionados = new ArrayList<Cromossomo>();
        
        //Ordena a lista original
        Collections.sort(cromossomos);
        
        //preserva o melhor
        selecionados.add(cromossomos.get(0));
        n--;
        
        //Pega o score do pior cromossomo
        double scoreMax = cromossomos.get(cromossomos.size()-1).getScore();
        
        //Vetor para controlar os cromossomos que já foram adicionados
        boolean[] adicionado = new boolean[cromossomos.size()];
        
        ArrayList<Integer> roleta = new ArrayList<Integer>();
        
        int divisao = 0;
        int contDivisao = 0;
        int nDivisoes = repeticao.length;
        int nPorDivisao = (int) cromossomos.size()/nDivisoes;
        
        for (int i = 1; i < cromossomos.size(); i++) {
            if(contDivisao == nPorDivisao){
                contDivisao = 0;
                divisao++;
            }
            
            if(divisao >= nDivisoes){
                break;
            }
            
            for (int j = 0; j < repeticao[divisao]; j++) {
                roleta.add(Integer.valueOf(i));
            }
            
            contDivisao++;           
        }
        
        //Embaralha a roleta
        Collections.shuffle(roleta);
        
        //Controla quantos cromossomos já foram adicionados
        int preenchidos = 0;
        
        //Seleciona com base na roleta
        for (int i = 0; i < roleta.size(); i++) {
            
            //Caso a lista de cromossomos esteja preenchida termina de preencher
            if(preenchidos == n){
                break;
            }
            
            int p = roleta.get(i).intValue();
            
            //Caso o cromossomo já tenha sido adicionado continua procurando
            if(adicionado[p]){
                continue;
            }
            
            //Adiciona o cromossomo e faz o controle
            selecionados.add(cromossomos.get(p));
            adicionado[p] = true;
            preenchidos++;
        }
        
        
        return selecionados;
    }
    
}
